const fs = require('fs')
const path = require('path')
const express = require('express')

const RUNTIME_SCRIPT_PATH = path.resolve(__dirname, '..', 'hmr/runtime.js')
const RUNTIME_SCRIPT_STR = fs.readFileSync(RUNTIME_SCRIPT_PATH).toString()

function getInsertedHTML(rawHTML, port) {
  const portInsertedHTML = `window.__WS_PORT = ${port}
  `
  return rawHTML.replace('</head>', '<script>' + portInsertedHTML + RUNTIME_SCRIPT_STR + '</script></head>')
}

function createMiddleware(config, wsPort) {
  return function middleware(req, res, next) {
    if (req.url === '/favicon.ico') {
      return res.sendStatus(404)
    }

    import('mime').then(({default: mime}) => {
      let filename = path.join(config.output.path, req.url.slice(1))
      let stat = fs.statSync(filename)
      if (stat.isFile()) {
        let content = fs.readFileSync(filename)
        let contentType = mime.getType(filename)
        res.setHeader('Content-Type', contentType)
        res.statusCode = res.statusCode || 200

        if (filename.endsWith('index.html')) {
          content = Buffer.from(getInsertedHTML(content.toString(), wsPort))
        }
        res.send(content)
      } else {
        return res.sendStatus(404)
      }
    })
  }
}

function createdBundleServer(config, port, wsPort) {
  const app = new express()

  const middleware = createMiddleware(config, wsPort)
  app.use(middleware)

  return {
    listen: app.listen.bind(app, port)
  }
}

module.exports = {
  createdBundleServer,
  getInsertedHTML,
  createMiddleware
}
